
// ===============================================================================================================
// -*- C++ -*-
//
// FmodSystem.cpp - FMOD sound system helper classes and functions.
//
// Copyright (c) 2011 Guilherme R. Lampert
// guilherme.ronaldo.lampert@gmail.com
//
// This code is licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// above is included in the resulting source code.
//
// ===============================================================================================================

#include <FmodSystem.hpp>

#ifdef _MSC_VER
#pragma comment (lib, "fmodvc.lib")
#endif

// =========================================================
// FMOD::SoundSystem Class Implementation
// =========================================================

bool FMOD::SoundSystem::initalized = false;

bool FMOD::SoundSystem::Initialize(int mixRate, int maxSoftwareChannels, unsigned int Flags)
{
	if (initalized)
	{
		Shutdown();
	}

	if ((FSOUND_GetVersion() >= FMOD_VERSION) && (FSOUND_Init(mixRate, maxSoftwareChannels, Flags)))
	{
		initalized = true;
	}

	return (initalized);
}

void FMOD::SoundSystem::Shutdown(void)
{
	FSOUND_Close();
	initalized = false;
}

bool FMOD::SoundSystem::Good(void)
{
	return (initalized);
}

FMOD::Sound * FMOD::SoundSystem::CreateSoundFromFile(const std::string & fileName)
{
	Sound * sptr = 0;

	if (initalized) // Load only if SoundSystem::Initialize() was called first!
	{
		try {
			sptr = new Sound(fileName);

			if (sptr->Fail())
			{
				LOG_ERROR("Failed to load the sound file: " << fileName);
				sptr->Release();
				sptr = 0;
			}
		}
		catch (...) {
			LOG_ERROR("Failed to load the sound file: " << fileName);
		}
	}

	return (sptr);
}

// =========================================================
// FMOD::Sound Class Implementation
// =========================================================

FMOD::Sound::Sound(const std::string & fileName) : sampleChannel(0), sample(0)
{
	if (!fileName.empty())
	{
		sample = FSOUND_Sample_Load(FSOUND_FREE, fileName.c_str(), 0, 0, 0);
	}
}

FMOD::Sound::~Sound(void)
{
	if (IsPlaying())
	{
		Stop();
	}

	if (sample)
	{
		FSOUND_Sample_Free(sample);
	}
}

unsigned long FMOD::Sound::AddRef(void) const
{
	return (++refCount);
}

unsigned long FMOD::Sound::Release(void) const
{
	if (--refCount == 0)
	{
		// Time to die...
		delete this;
		return (0);
	}

	return (refCount);
}

unsigned long FMOD::Sound::ReferenceCount(void) const
{
	return (refCount);
}

bool FMOD::Sound::IsPlaying(void) const
{
	return ((FSOUND_IsPlaying(sampleChannel)) ? true : false);
}

void FMOD::Sound::SetVolume(int volume)
{
	FSOUND_SetVolume(sampleChannel, volume);
}

void FMOD::Sound::SetVolumeAbsolute(int volume)
{
	FSOUND_SetVolumeAbsolute(sampleChannel, volume);
}

void FMOD::Sound::Play(void)
{
	sampleChannel = FSOUND_PlaySound(FSOUND_FREE, sample);
}

void FMOD::Sound::Stop(void)
{
	FSOUND_StopSound(sampleChannel);
}